"use strict";
// 01命令行改代码
// 在命令行中安装TypeScript全局依赖，以便在任何目录下都能使用tsc命令
// npm i typescript -g
// 使用tsc命令将TypeScript文件编译为JavaScript文件
// tsc index.ts
// 02自动化编译
// 安装ts-node模块
// tsc --init
// tdc --watch
// 03数据类型
let num = 10;
let str = "hello";
let bool = true;
let zi;
// 字面量类型，只能存放hello
// 04总览所有类型
// js：
// string  number  boolean  null underfined  bigint  symbol  object(Array  Function  Data Error)
// ts:
// 以上 + 
// any unknown never void tuple enum 自定义：type interface
// 05 any类型
// 特点
// 可以赋值给任意类型
// 可以赋值给任意变量
let a;
a = 10;
console.log(a);
// 显示
let b;
// 隐式
a = 10;
console.log(typeof a);
a = "hello";
console.log(typeof a);
// any可以给任意类型赋值，但同时会影响到其他类型
let c;
c = a;
console.log(typeof c);
// 06 unknown类型
// 特点
// 也可以赋值给任意类型
// 但会报错
let d;
let e;
d = 10;
// e = d
// console.log(e.toUpperCase())
// 解决报错：
// 1.加条件判断
if (typeof d === "number") {
    e = d;
}
// 2.类型断言
e = d;
e = d;
//07never类型
// 特点
// 1.never类型不能有任何值
// 不要给变量赋值为never类型
let f;
// f = 10 // 报错
// 2.never可限制函数的返回值（函数没有返回值）
function fn() {
    throw new Error("错误");
}
// 3.有时是typescript推断出的
let g = "hello";
if (typeof g === "string") {
    console.log(g.toUpperCase());
}
else {
    console.log(g); // g为never
}
// 08 void类型
// 特点
// 1.void类型一般用于函数没有返回值的情况（限制）
// 2.void类型可接受undefined(函数可隐式返回值)
function fn1(msg) {
    console.log(msg);
} // js函数默认返回值为undefined
// 3.不能对void函数的返回值进行操作
let h = fn1("hello");
// h.toUpperCase()// 报错
// 09object类型
// （1）object类型
// 特点
// 1.可以存所有非原始类型【数组，函数，对象等.即除了number string boolean以及null undefined】，范围宽泛，一般不使用
let i;
i = {
    name: "张三",
};
i = [1, 2, 3];
i = function () { };
i = new Date();
i = {};
// （2）Object类型
// 特点
// 1.除了null和undefined，其他类型都可以赋值给Object类型，范围更大，基本不用
// （3）声明对象类型格式
// 1.对象字面量
let j; // 声明对象的属性和属性值的类型
j = {
    name: "张三", //也可以用封号和回车分隔
    age: 18 //必须两个都写，若想少写，声明加问号
};
// 2.索引签名
let k; //可任意添加值
k = {
    name: "张三",
    age: 18,
    sex: "男"
};
// （4）声明函数格式
let count; // 声明函数的形参和返回值的类型(箭头函数)
count = function (x, y) {
    return x + y;
};
// (5)声明数组类型
let arr1; // 声明数组的元素类型
arr1 = [1, 2, 3];
let arr2; // 声明数组的元素类型(泛型)
arr2 = [1, 2, 3];
// 10tuple元组类型
// 前言
// 元组类型不是一个关键字，是数组类型的扩展，数组类型可以存放任意类型的元素，元组类型可以存放指定类型的元素
// 特点
// 1.元组类型可以存放指定类型的元素
let tup1; // 声明元组的元素类型
let tup2; // 可加问号,表示可省略
let tup3; // 表示可加任意数量的字符串,但三种数据类型位置需要固定
tup1 = [1, "hello", true];
tup2 = [1, "hello", true];
tup3 = [1, "hello", "world", "!", "!", true];
// 11enum枚举类型
// 前言
// 1.1枚举类型是一种特殊的类型，它可以将一组相关的值组合在一起，方便使用（有了含义命名后，不容易出错）
// 1.2常亮
// 类型
// 2.1数字枚举（自动递增，有数字与值的反向映射
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
    Direction[Direction["Left"] = 2] = "Left";
    Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));
function walk(data) {
    switch (data) {
        case Direction.Up:
            console.log("上");
        case Direction.Down:
            console.log("下");
        case Direction.Left:
            console.log("左");
        case Direction.Right:
            console.log("右");
    }
}
// 2.2字符串枚举（无反向映射，常用在API）
var Color;
(function (Color) {
    Color["red"] = "hong";
    Color["blue"] = "lan";
    Color["yellow"] = "huang";
})(Color || (Color = {}));
function choose(point) {
    switch (point) {
        case Color.blue:
            console.log("蓝");
        case Color.red:
            console.log("红");
        case Color.yellow:
            console.log("黄");
    }
}
console.log(0 /* Direction2.up */);
let price = 10;
function logGender(xxx) {
    console.log(xxx);
}
logGender("男"); //只能在男女中选
const house = {
    height: 180,
    width: 75,
    lou: 6,
    cell: 4,
    room: "701"
};
//13void的特殊情况
// 1.1边定义边声明，函数返回值只能为undefined
function auv(isBeijing) {
    console.log(isBeijing);
}
const f1 = function () {
    return 66; //返回值类型不为void，但未报错
};
// 14class类
// 1.类
class Person {
    constructor(name, age) {
        this.name = name; //将形参name传给数据成员name
        this.age = age;
    }
    speak() {
        console.log(`我叫：${this.name}，今年${this.age}岁了`);
    }
} //结尾不加;
const p1 = new Person("李同学", 18); //构建对象
p1.speak();
// 2.继承
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age); //继承父类的数据成员
        this.grade = grade; //初始化新数据成员
    }
    study() {
        console.log(`${this.name}正在努力学习中……`);
    }
    speak() {
        console.log(this.grade);
    }
}
const s1 = new Student("刘同学", 19, "高三"); //构建对象
s1.study(); //调用study
s1.speak();
// 15属性修饰符public protected private readonly
// （1）public
// 1.1默认为public,范围与c++一样
// 1.2可简写，如class Person{constructor(public name:string,public age:number){}}
// （2）protected private与c++基本一致
// （3）readonly
class Car {
    constructor(vin) {
        this.vin = vin;
    }
}
const c1 = new Car(123456);
console.log(c1.vin); //可读
// c1.vin = 789    //不可改
// 16抽象类
// 特点
// 1.无法被实例化，存在意义为被继承，其中可有普通方法和抽象方法
class Package {
    constructor(weight) {
        this.weight = weight;
    }
    //具体方法
    printPackage() {
        console.log(`重量为${this.weight}，运费为${this.calculate}`);
    }
}
class StandardPackage extends Package {
    constructor(weight, perPrice) {
        super(weight);
        this.perPrice = perPrice;
    }
    calculate() {
        return this.weight * this.perPrice;
    }
}
const stand1 = new StandardPackage(55, 12); //子类的实例
stand1.printPackage(); //调用抽象类的具体方法来显示价格
class Person1 {
    constructor(weight, name) {
        this.weight = weight;
        this.name = name;
    }
    speak(n) {
        for (let i = 0; i < n; i++) {
            console.log(`我是${this.name}，体重为${this.weight}kg`);
        }
    }
}
const p2 = new Person1(77, "lxh");
p2.speak(4);
const Qwe = {
    name: "lxh",
    gerder: "man",
    age: 18,
    run(n) {
        console.log(`跑了${n}米`);
    }
};
Qwe.run(50);
const count1 = (x, y) => {
    return x + y;
};
const teacher1 = {
    name: "lxh",
    age: 18,
    grade: "fifteen"
};
const human = {
    name: "lxh",
    age: 18,
    grade: "dayi"
};
// 18概念辨析
// 1.interface和type的区别
// 1.1偏向：前者偏向类和对象，后者偏向类型别名、交叉类型（&）、联合类型（|）
// 1.2两者多数情况下可转换（前者的合并和继承 = 后者的交叉）
// 2.interface和抽象类abstract
// 2.1都可以定义类的格式
// 2.2前者只能描述结构，不能实现代码；后者可含抽象与具体的方法 
// 2.3一个类可实现多个接口，但只能有一个抽象类
//19泛型（把数据类型视作变量）
// 1.泛型函数
function LogData(data1, data2) {
    console.log(data1);
    console.log(data2);
    return Date.now() % 2 ? data1 : data2;
}
LogData(100, true); //现在T是number
LogData("123", 123); //现在T是string
let p = {
    name: "lxh",
    extroInfo: 123
};
// 20类型声明文件
// 常用.d.ts后缀文件，为现有js文件提供类型信息，便于ts使用js的库和模块
